<template>
  <div class="contest-live-container">
    <el-container>
      <el-header>
        <div class="header-content">
          <div class="contest-info">
            <h2>{{ contestDetail && contestDetail.title }}</h2>
            <div class="timer" v-if="statusVO">
              <template v-if="statusVO.status === 1">
                <!-- 答题中状态 -->
                <span class="status answering">答题中</span>
                <span>第 {{ (statusVO.currentQuestionIndex || 0) + 1 }} / {{ statusVO.totalQuestions }} 题</span>
              </template>
              <template v-else-if="statusVO.status === 2">
                <!-- 等待下一题状态 -->
                <span class="status waiting">等待中</span>
                <span>下一题倒计时: {{ waitingSeconds }}秒</span>
              </template>
              <template v-else-if="statusVO.status === 3">
                <!-- 已结束状态 -->
                <span class="status ended">已结束</span>
              </template>
              <template v-else-if="statusVO.status === 4">
                <!-- 准备中状态 -->
                <span class="status preparing">准备中</span>
                <span>距离开始: {{ waitingSeconds }}秒</span>
              </template>
              <template v-else>
                <!-- 等待开始状态 -->
                <span class="status waiting">等待开始</span>
              </template>
            </div>
          </div>
          <div class="actions">
            <el-button size="small" @click="goBack">返回竞赛</el-button>
            <el-button size="small" type="danger" v-if="isAdmin && statusVO && (statusVO.status === 1 || statusVO.status === 2)" @click="endContest">结束竞赛</el-button>
            <el-button size="small" type="success" v-if="isAdmin && statusVO && statusVO.status === 2" @click="manualNextQuestion">下一题</el-button>
          </div>
        </div>
      </el-header>
      
      <el-container class="main-content">
        <el-aside width="300px">
          <div class="leaderboard-container">
            <h3>实时排行榜</h3>
            <div class="leaderboard">
              <el-table :data="leaderboard" height="calc(100vh - 200px)" :row-class-name="leaderboardRowClassName">
                <el-table-column prop="rank" label="排名" width="60" />
                <el-table-column label="用户" min-width="120">
                  <template #default="scope">
                    <div class="user-info">
                      <el-avatar :size="30" :src="scope.row.avatar"></el-avatar>
                      <span class="username">{{ scope.row.username }}</span>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column prop="score" label="得分" width="60" />
                <el-table-column label="状态" width="60">
                  <template #default="scope">
                    <el-tag :type="getAnswerStatusType(scope.row.answerStatus)" size="mini">
                      {{ getAnswerStatusText(scope.row.answerStatus) }}
                    </el-tag>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </div>
        </el-aside>
        
        <el-main>
          <div class="question-container" v-if="currentQuestion">
            <div class="question-content">
              <h3>{{ currentQuestion.title }}</h3>
              <div class="question-description" v-html="currentQuestion.content"></div>
              
              <!-- 选择题 -->
              <div v-if="currentQuestion.typeId === 1" class="options-container">
                <el-radio-group v-model="userAnswer" :disabled="answered || statusVO.status !== 1">
                  <el-radio v-for="option in currentQuestion.options" :key="option.id" :label="option.code" class="option-item">
                    {{ option.code }}. {{ option.content }}
                  </el-radio>
                </el-radio-group>
              </div>
              
              <!-- 多选题 -->
              <div v-else-if="currentQuestion.typeId === 2" class="options-container">
                <el-checkbox-group v-model="userAnswer" :disabled="answered || statusVO.status !== 1">
                  <el-checkbox v-for="option in currentQuestion.options" :key="option.id" :label="option.code" class="option-item">
                    {{ option.code }}. {{ option.content }}
                  </el-checkbox>
                </el-checkbox-group>
              </div>
              
              <!-- 判断题 -->
              <div v-else-if="currentQuestion.typeId === 3" class="options-container">
                <el-radio-group v-model="userAnswer" :disabled="answered || statusVO.status !== 1">
                  <el-radio label="true" class="option-item">正确</el-radio>
                  <el-radio label="false" class="option-item">错误</el-radio>
                </el-radio-group>
              </div>
              
              <!-- 填空题 -->
              <div v-else-if="currentQuestion.typeId === 4" class="text-answer-container">
                <el-input v-model="userAnswer" type="text" placeholder="请输入答案" :disabled="answered || statusVO.status !== 1" />
              </div>
              
              <!-- 简答题 -->
              <div v-else class="text-answer-container">
                <el-input v-model="userAnswer" type="textarea" rows="4" placeholder="请输入答案" :disabled="answered || statusVO.status !== 1" />
              </div>
              
              <div class="question-actions">
                <el-button type="primary" @click="submitAnswer" :disabled="!canSubmit">提交答案</el-button>
              </div>
            </div>
            
            <!-- 答题结果 -->
            <div v-if="answerResult" class="answer-result">
              <div v-if="answerResult.correct" class="result correct">
                <i class="el-icon-success"></i>
                <span>回答正确！获得 {{ answerResult.score }} 分</span>
              </div>
              <div v-else class="result incorrect">
                <i class="el-icon-error"></i>
                <span>回答错误</span>
                <div class="correct-answer" v-if="answerResult.correctAnswer">
                  <span>正确答案: {{ answerResult.correctAnswer }}</span>
                </div>
              </div>
            </div>
          </div>
          
          <!-- 等待下一题 -->
          <div v-else-if="statusVO && statusVO.status === 2" class="waiting-container">
            <div class="waiting-content">
              <h3>等待下一题</h3>
              <div class="countdown">{{ waitingSeconds }}</div>
              <div class="hint">下一题即将开始...</div>
            </div>
          </div>
          
          <!-- 竞赛已结束 -->
          <div v-else-if="statusVO && statusVO.status === 3" class="ended-container">
            <div class="ended-content">
              <h3>竞赛已结束</h3>
              <div class="message">感谢参与，您可以在竞赛详情页查看最终排名</div>
              <el-button type="primary" @click="goBack">返回竞赛详情</el-button>
            </div>
          </div>
          
          <!-- 准备中状态 -->
          <div v-else-if="statusVO && statusVO.status === 4" class="preparing-container">
            <div class="preparing-content">
              <h3>即将开始</h3>
              <div class="countdown">{{ waitingSeconds }}</div>
              <div class="hint">请做好准备，竞赛将在倒计时结束后自动开始</div>
            </div>
          </div>
          
          <!-- 等待开始 -->
          <div v-else class="waiting-container">
            <div class="waiting-content">
              <h3>等待竞赛开始</h3>
              <div class="hint">竞赛将在{{ formatStartTime }}自动开始</div>
            </div>
          </div>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script>
import { getContestDetail } from '@/api/contest'
import { 
  getLiveContestStatus, 
  startLiveContest, 
  endLiveContest, 
  getCurrentQuestion, 
  submitLiveAnswer, 
  getLiveLeaderboard,
  nextQuestion
} from '@/api/live'
import { getUserInfo } from '@/api/user'
import websocket from '@/utils/websocket'

export default {
  name: 'ContestLive',
  
  data() {
    return {
      contestId: null,
      contestDetail: null,
      loading: false,
      
      // 用户信息
      userId: null,
      isAdmin: false,
      
      // 竞赛状态
      statusVO: null,
      statusInterval: null,
      
      // 题目相关
      currentQuestion: null,
      userAnswer: '',
      answered: false,
      answerResult: null,
      
      // 排行榜
      leaderboard: [],
      leaderboardInterval: null,
      
      // 倒计时
      waitingSeconds: 0,
      waitingInterval: null,
      
      // 竞赛开始时间
      contestStartTime: null
    }
  },
  
  computed: {
    canSubmit() {
      return this.statusVO && 
             this.statusVO.status === 1 && 
             this.currentQuestion && 
             !this.answered && 
             this.userAnswer !== ''
    },
    
    // 格式化开始时间
    formatStartTime() {
      if (!this.contestStartTime) return '';
      const startTime = new Date(this.contestStartTime);
      return `${startTime.getFullYear()}-${String(startTime.getMonth() + 1).padStart(2, '0')}-${String(startTime.getDate()).padStart(2, '0')} ${String(startTime.getHours()).padStart(2, '0')}:${String(startTime.getMinutes()).padStart(2, '0')}`;
    }
  },
  
  created() {
    this.contestId = this.$route.params.id
    this.init()
  },
  
  beforeUnmount() {
    this.clearAllIntervals()
    this.disconnectWebSocket()
  },
  
  methods: {
    async init() {
      this.loading = true
      try {
        // 获取竞赛信息
        const { data: contestData } = await getContestDetail(this.contestId)
        this.contestDetail = contestData
        
        // 获取用户信息
        const { data: userData } = await getUserInfo()
        this.userId = userData.id
        this.isAdmin = userData.roleId === 1 || userData.roleId === 2 // 管理员或教师
        
        // 获取竞赛状态
        await this.getStatus()
        
        // 获取排行榜
        await this.getLeaderboard()
        
        // 连接WebSocket
        this.connectWebSocket()
        
        // 设置定时任务
        this.setupIntervals()
      } catch (error) {
        console.error('初始化失败', error)
        this.$message.error('加载竞赛信息失败')
      } finally {
        this.loading = false
      }
    },
    
    // 竞赛状态相关
    async getStatus() {
      try {
        const { data } = await getLiveContestStatus(this.contestId)
        this.statusVO = data
        
        // 保存竞赛开始时间
        if (data.scheduledStartTime) {
          this.contestStartTime = data.scheduledStartTime;
        }
        
        // 如果在准备中状态，设置倒计时
        if (this.statusVO.status === 4 && this.statusVO.waitingSeconds > 0) {
          this.setupPrepareCountdown()
        }
        
        // 如果在等待状态，设置倒计时
        if (this.statusVO.status === 2 && this.statusVO.nextQuestionTime) {
          this.setupWaitingCountdown()
        }
        
        // 如果当前有题目，加载题目
        if (this.statusVO.status === 1 && this.statusVO.currentQuestionId) {
          await this.getCurrentQuestion()
        }
      } catch (error) {
        console.error('获取竞赛状态失败', error)
      }
    },
    
    // 获取当前题目
    async getCurrentQuestion() {
      try {
        const { data } = await getCurrentQuestion(this.contestId)
        this.currentQuestion = data
        this.userAnswer = ''
        this.answered = false
        this.answerResult = null
      } catch (error) {
        console.error('获取当前题目失败', error)
      }
    },
    
    // 获取排行榜
    async getLeaderboard() {
      try {
        const { data } = await getLiveLeaderboard(this.contestId)
        this.leaderboard = data
      } catch (error) {
        console.error('获取排行榜失败', error)
      }
    },
    
    // 提交答案
    async submitAnswer() {
      if (!this.canSubmit) return
      
      try {
        const answerData = {
          questionId: this.currentQuestion.id,
          answer: this.formatAnswer()
        }
        
        const { data } = await submitLiveAnswer(this.contestId, answerData)
        this.answered = true
        this.answerResult = data
        
        // 根据答案更新本地排行榜中的用户状态
        this.updateLocalLeaderboardStatus()
      } catch (error) {
        console.error('提交答案失败', error)
        this.$message.error(error.message || '提交答案失败')
      }
    },
    
    // 格式化答案数据
    formatAnswer() {
      if (!this.userAnswer) return ''
      
      // 多选题，将数组转为逗号分隔的字符串
      if (this.currentQuestion.typeId === 2 && Array.isArray(this.userAnswer)) {
        return this.userAnswer.sort().join(',')
      }
      
      return this.userAnswer
    },
    
    // 更新本地排行榜中的用户状态
    updateLocalLeaderboardStatus() {
      if (!this.answerResult || !this.leaderboard) return
      
      const userIndex = this.leaderboard.findIndex(item => item.userId === this.userId)
      if (userIndex !== -1) {
        const newStatus = this.answerResult.correct ? 1 : 2 // 1-答对，2-答错
        this.$set(this.leaderboard[userIndex], 'answerStatus', newStatus)
      }
    },
    
    // 启动竞赛（管理员）
    async startContest() {
      try {
        await startLiveContest(this.contestId)
        this.$message.success('竞赛已开始')
        await this.getStatus()
      } catch (error) {
        console.error('启动竞赛失败', error)
        this.$message.error(error.message || '启动竞赛失败')
      }
    },
    
    // 结束竞赛（管理员）
    async endContest() {
      try {
        await this.$confirm('确定要结束当前竞赛吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
        
        await endLiveContest(this.contestId)
        this.$message.success('竞赛已结束')
        await this.getStatus()
      } catch (error) {
        if (error === 'cancel') return
        console.error('结束竞赛失败', error)
        this.$message.error(error.message || '结束竞赛失败')
      }
    },
    
    // 手动进入下一题（管理员）
    async manualNextQuestion() {
      try {
        await nextQuestion(this.contestId)
        this.$message.success('已进入下一题')
      } catch (error) {
        console.error('进入下一题失败', error)
        this.$message.error(error.message || '进入下一题失败')
      }
    },
    
    // WebSocket相关
    connectWebSocket() {
      websocket.connectToLiveContest(this.contestId, this.userId)
        .then(() => {
          console.log('已连接到实时竞赛WebSocket')
          this.setupWebSocketListeners()
        })
        .catch(error => {
          console.error('WebSocket连接失败', error)
          this.$message.error('实时连接失败，将使用轮询方式获取数据')
        })
    },
    
    disconnectWebSocket() {
      websocket.disconnect()
    },
    
    setupWebSocketListeners() {
      // 监听消息
      websocket.on('message', this.handleWebSocketMessage)
      
      // 监听连接关闭
      websocket.on('close', () => {
        console.log('WebSocket连接已关闭，将使用轮询方式获取数据')
      })
    },
    
    handleWebSocketMessage(data) {
      if (!data || !data.type) return
      
      switch (data.type) {
        case 1: // 竞赛状态更新
          this.statusVO = data.data
          
          // 如果是准备中状态，设置倒计时
          if (this.statusVO.status === 4) {
            this.setupPrepareCountdown()
          }
          
          // 如果是等待下一题状态，设置倒计时
          if (this.statusVO.status === 2) {
            this.setupWaitingCountdown()
          }
          break
        case 2: // 新题目
          this.currentQuestion = data.data
          this.userAnswer = ''
          this.answered = false
          this.answerResult = null
          break
        case 3: // 答题结果
          // 只处理自己的答题结果
          if (data.data && data.data.userId === this.userId) {
            this.answerResult = data.data
            this.answered = true
          }
          break
        case 4: // 排名更新
          this.leaderboard = data.data
          break
        case 5: // 等待下一题
          this.statusVO = data.data
          this.setupWaitingCountdown()
          break
        case 6: // 竞赛结束
          this.statusVO = data.data
          this.clearAllIntervals()
          this.$message.info('竞赛已结束')
          break
      }
    },
    
    // 设置倒计时
    setupPrepareCountdown() {
      // 清除之前的倒计时
      if (this.waitingInterval) {
        clearInterval(this.waitingInterval)
      }
      
      // 设置倒计时
      this.waitingSeconds = this.statusVO.waitingSeconds
      
      // 每秒倒计时
      this.waitingInterval = setInterval(() => {
        if (this.waitingSeconds > 0) {
          this.waitingSeconds--
        } else {
          // 倒计时结束，刷新状态
          clearInterval(this.waitingInterval)
          this.getStatus()
        }
      }, 1000)
    },
    
    // 设置等待下一题倒计时（原有方法保持不变）
    setupWaitingCountdown() {
      if (!this.statusVO || !this.statusVO.waitingSeconds) return
      
      // 清除之前的计时器
      if (this.waitingInterval) {
        clearInterval(this.waitingInterval)
      }
      
      this.waitingSeconds = this.statusVO.waitingSeconds
      
      // 创建新的计时器
      this.waitingInterval = setInterval(() => {
        if (this.waitingSeconds > 0) {
          this.waitingSeconds--
        } else {
          clearInterval(this.waitingInterval)
        }
      }, 1000)
    },
    
    // 设置定时轮询任务
    setupIntervals() {
      // 每30秒获取一次状态
      this.statusInterval = setInterval(() => {
        this.getStatus()
      }, 30000)
      
      // 每60秒获取一次排行榜
      this.leaderboardInterval = setInterval(() => {
        this.getLeaderboard()
      }, 60000)
    },
    
    // 清除所有定时任务
    clearAllIntervals() {
      if (this.statusInterval) clearInterval(this.statusInterval)
      if (this.leaderboardInterval) clearInterval(this.leaderboardInterval)
      if (this.waitingInterval) clearInterval(this.waitingInterval)
    },
    
    // 排行榜行样式
    leaderboardRowClassName({row}) {
      if (row.userId === this.userId) {
        return 'current-user-row'
      }
      return ''
    },
    
    // 获取答题状态文本
    getAnswerStatusText(status) {
      switch (status) {
        case 0: return '未答'
        case 1: return '答对'
        case 2: return '答错'
        default: return '未知'
      }
    },
    
    // 获取答题状态类型
    getAnswerStatusType(status) {
      switch (status) {
        case 0: return 'info'
        case 1: return 'success'
        case 2: return 'danger'
        default: return 'info'
      }
    },
    
    // 返回竞赛详情
    goBack() {
      this.$router.push(`/contest/detail/${this.contestId}`)
    }
  }
}
</script>

<style scoped>
.contest-live-container {
  height: 100%;
}

.el-container {
  height: 100%;
}

.el-header {
  background-color: #f5f7fa;
  padding: 0 20px;
  height: auto !important;
  line-height: normal;
  border-bottom: 1px solid #e4e7ed;
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 0;
}

.contest-info {
  display: flex;
  flex-direction: column;
}

.contest-info h2 {
  margin: 0;
  font-size: 20px;
}

.timer {
  display: flex;
  align-items: center;
  margin-top: 5px;
  font-size: 14px;
}

.timer .status {
  margin-right: 10px;
  padding: 2px 8px;
  border-radius: 4px;
  color: white;
}

.timer .status.answering {
  background-color: #409eff;
}

.timer .status.waiting {
  background-color: #e6a23c;
}

.timer .status.ended {
  background-color: #f56c6c;
}

.main-content {
  height: calc(100vh - 80px);
}

.el-aside {
  background-color: #fff;
  border-right: 1px solid #e4e7ed;
  padding: 20px;
}

.leaderboard-container h3 {
  margin-top: 0;
}

.user-info {
  display: flex;
  align-items: center;
}

.username {
  margin-left: 10px;
}

.current-user-row {
  background-color: #f0f9eb;
}

.el-main {
  padding: 20px;
  background-color: #f9f9f9;
}

.question-container {
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  padding: 20px;
}

.question-content h3 {
  margin-top: 0;
}

.question-description {
  margin-bottom: 20px;
}

.options-container {
  margin-bottom: 20px;
}

.option-item {
  display: block;
  margin-bottom: 10px;
}

.text-answer-container {
  margin-bottom: 20px;
}

.question-actions {
  margin-top: 20px;
  text-align: center;
}

.answer-result {
  margin-top: 20px;
  padding: 15px;
  border-radius: 4px;
}

.result {
  display: flex;
  align-items: center;
}

.result i {
  font-size: 24px;
  margin-right: 10px;
}

.result.correct {
  color: #67c23a;
  background-color: #f0f9eb;
  border: 1px solid #c2e7b0;
}

.result.incorrect {
  color: #f56c6c;
  background-color: #fef0f0;
  border: 1px solid #fbc4c4;
}

.correct-answer {
  margin-top: 10px;
}

.waiting-container, .ended-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
}

.waiting-content, .ended-content {
  text-align: center;
  background-color: #fff;
  padding: 40px;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.countdown {
  font-size: 60px;
  margin: 20px 0;
  color: #409eff;
  font-weight: bold;
}

.hint {
  color: #606266;
  margin-bottom: 20px;
}

.message {
  margin: 20px 0;
  color: #606266;
}

.status {
  padding: 4px 8px;
  border-radius: 4px;
  font-weight: bold;
  margin-right: 8px;
  
  &.answering {
    background-color: #e6f7ff;
    color: #1890ff;
  }
  
  &.waiting {
    background-color: #fff7e6;
    color: #fa8c16;
  }
  
  &.ended {
    background-color: #f6ffed;
    color: #52c41a;
  }
  
  &.preparing {
    background-color: #f9f0ff;
    color: #722ed1;
  }
}

.preparing-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  
  .preparing-content {
    text-align: center;
    
    h3 {
      font-size: 24px;
      margin-bottom: 20px;
      color: #722ed1;
    }
    
    .countdown {
      font-size: 64px;
      font-weight: bold;
      margin: 20px 0;
      color: #722ed1;
    }
    
    .hint {
      font-size: 16px;
      color: #666;
      margin-bottom: 30px;
    }
  }
}
</style> 